﻿using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using rsdeploygui.ReportService2010;
using System.Web.Services;

namespace rsdeploygui
{
    public partial class Main : Form
    {
        TextBoxWriter writer = null;
        String[] Actions = { "Copy Items", "Delete Items", "Refresh Linked Reports", "View Properties" };

        public Main()
        {
            InitializeComponent();
            // form title text
            this.Text = "Report Services Management Utility";
            // Populate the Action combo box
            cboSelectAction_Populate();

            // initialize the textbox writer for logging
            writer = new TextBoxWriter(txtLog);
            Console.SetOut(writer);
            Console.WriteLine("Initialization complete");
        }

        /// <summary>
        /// populate the Action drop down
        /// </summary>
        private void cboSelectAction_Populate()
        {
            // get the list of actions from the array
            this.cboSelectAction.DataSource = Actions;
        }

        private void cboSelectAction_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cboSelectAction.SelectedItem.ToString().Length > 0)
            {
                this.grpStep2.Enabled = true;
                // populate the URL selection combo box
                GenerateSrcComboBox();
                if (this.cboSelectAction.SelectedItem.ToString() == "Copy Items")
                // set up the form to allow users to select a source and destination
                {
                    // enable the check box group to select items
                    this.grpCatItemsSelection.Enabled = true;
                    // make sure the destination information is viewable
                    this.grpStep3.Visible = true;
                    // change all the appropriate labels
                    this.grpStep2.Text = "Step 2 - Select Source";
                    this.lblcboSrcURL.Text = "Source Report Server URL";
                    this.grpLastStep.Text = "Step 4 - Copy selected items";
                    this.btnAction.Text = "Copy selected items";
                    // allow multiple selections
                    this.treeView1.CheckBoxes = true;
                }
                if (this.cboSelectAction.SelectedItem.ToString() == "Delete Items")
                // set up the form for deleting catalog items
                {
                    this.grpCatItemsSelection.Visible = false;
                    this.grpStep3.Visible = false;
                    this.grpStep2.Text = "Step 2 - Select server and items to delete";
                    this.lblcboSrcURL.Text = "Report Server URL";
                    this.grpLastStep.Text = "Step 3 - Delete selected items";
                    this.btnAction.Text = "Delete selected items";
                    // this is a delete operation, so we only want to allow selection of one folder
                    this.treeView1.CheckBoxes = false;
                }
                if (this.cboSelectAction.SelectedItem.ToString() == "Refresh Linked Reports")
                // refresh all selected linked reports
                {
                    this.grpCatItemsSelection.Visible = false;
                    this.grpStep3.Visible = false;
                    this.grpStep2.Text = "Step 2 - Select server and linked reports to refresh";
                    this.lblcboSrcURL.Text = "Report Server URL";
                    this.grpLastStep.Text = "Step 3 - Refresh selected items";
                    // Enable the Action button
                    this.btnAction.Text = "Refresh selected items";
                    this.btnAction.Enabled = true;
                    // allow multiple selections in the tree view
                    this.treeView1.CheckBoxes = true;
                }
                if (this.cboSelectAction.SelectedItem.ToString() == "View Properties")
                // view the properties of the selected items
                {
                    this.grpCatItemsSelection.Visible = false;
                    this.grpStep3.Visible = false;
                    this.grpStep2.Text = "Step 2 - Select item to view properties of";
                    this.lblcboSrcURL.Text = "Report Server URL";
                    this.grpLastStep.Text = "Step 3 - View Properties";
                    this.btnAction.Text = "View Properties";
                    // allow multiple selections in the tree view
                    this.treeView1.CheckBoxes = true;
                }
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.Save();
        }

        private void btnAction_Click(object sender, EventArgs e)
        {
            List<ReportService2010.CatalogItem> SelectedNodes = getChecked(treeView1.Nodes);
            // Make sure the tree node has selection before moving forward
            if (SelectedNodes.Count>0)
            {
                // if the action selected is to copy items
                if ((cboSelectAction.SelectedItem.ToString() == "Copy Items"))
                {
                    // check to make sure something is selected in the destination tree view
                    if (!(treeView2.SelectedNode == null))
                    {
                        if (chkCreateFolders.Checked)
                        {
                            CopyFolders();
                            //refresh the TreeView for destination
                            GenerateDstTreeView();
                        }
                        if (chkCreateDataSources.Checked)
                        {
                            //copy the data sources 

                        }
                        if (chkDatasets.Checked)
                        {
                            CopyDataSets();
                        }
                        if (chkLinkedReports.Checked)
                        {
                            CopyLinkedReports();
                        }
                        // regenerate the dst tree view
                        GenerateDstTreeView();
                    }
                    else
                    {
                        Console.WriteLine("Select a destination folder!");
                    }
                } 
                else if (cboSelectAction.SelectedItem.ToString() == "Delete Items")
                // if the action selected is to delete items
                {
                    // future functionality -- need to handle other catalogitem types other than just
                    // folders here
                    Folder fld = new Folder(cboSrcURL.SelectedItem.ToString());
                    ReportService2010.CatalogItem flderToDelete = (ReportService2010.CatalogItem)treeView1.SelectedNode.Tag;
                    fld.Delete(flderToDelete.Path);
                    // regenerate the source tree view
                    GenerateSrcTreeView();
                }
                else if (cboSelectAction.SelectedItem.ToString() == "Refresh Linked Reports")
                //Refresh Linked Reports
                {
                    RefreshLinkedReports();
                }
                else if (cboSelectAction.SelectedItem.ToString() == "View Properties")
                // view properties of all selected catalog items
                {
                    ViewProperties();
                }

            }
            else
                // what happens if there is no folder selected
            {
                Console.WriteLine("Select at least one item!");
            }
        }
        private void ViewProperties()
        {
            foreach (TreeNode tn in getCheckedTreeNodes(treeView1.Nodes))
            {
                ReportService2010.CatalogItem ci = (ReportService2010.CatalogItem)tn.Tag;
                rsdeploygui.CatalogItem cim = new rsdeploygui.CatalogItem(cboSrcURL.SelectedItem.ToString());
                cim.ViewProperties(ci.Path);
            }
        }
        /// <summary>
        /// Refresh all the linked reports selected in the src tree view
        /// </summary>
        private void RefreshLinkedReports()
        {
            Console.WriteLine("Refreshing LinkedReports...");
            int count = 0;

            foreach (TreeNode tn in getCheckedTreeNodes(treeView1.Nodes))
            {
                ReportService2010.CatalogItem ci = (ReportService2010.CatalogItem)tn.Tag;

                if (ci.TypeName == "LinkedReport")
                {
                    // create a new linked report object with the source url
                    LinkedReport lr = new LinkedReport(cboSrcURL.SelectedItem.ToString());
                    // get the path of the linked report to refresh from the Node tag
                    ReportService2010.CatalogItem lrToRefresh = ci;

                    if (lr.HasValidReportLink(ci.Path))
                    {
                        // Call the refresh linked item method with the path
                        lr.RefreshLinkedItem(lrToRefresh.Path, lr.GetItemLink(ci.Path));
                    }
                    count += 1;
                }
            }
            Console.WriteLine("Refreshing LinkedReports complete, {0} refreshed", count);
        }

        /// <summary>
        /// Get the checked nodes in a Treeview
        /// </summary>
        /// <param name="nc"></param>
        /// <returns>a list of catalog items</returns>
        private List<TreeNode> getCheckedTreeNodes(TreeNodeCollection nc)
        {
            List<TreeNode> ciResult = new List<TreeNode>();
            if (nc != null)
            {
                foreach (TreeNode tn in nc)
                {
                    if (tn.Checked)
                    {
                        ciResult.Add(tn);
                    }
                    ciResult.AddRange(getCheckedTreeNodes(tn.Nodes));
                }
            }
            return ciResult;
        }

        /// <summary>
        /// Get the checked nodes in a Treeview
        /// </summary>
        /// <param name="nc"></param>
        /// <returns>a list of catalog items</returns>
        private List<ReportService2010.CatalogItem> getChecked(TreeNodeCollection nc)
        {
            List<ReportService2010.CatalogItem> ciResult = new List<ReportService2010.CatalogItem>();
            if (nc != null)
            {
                foreach (TreeNode tn in nc)
                {
                    if (tn.Checked)
                    {
                        ciResult.Add((ReportService2010.CatalogItem)tn.Tag);
                    }
                    ciResult.AddRange(getChecked(tn.Nodes));
                }
            }
            return ciResult;
        }

        /// <summary>
        /// Changes all child nodes under a given treenode to whatever nodeChecked is.
        /// From http://social.msdn.microsoft.com/Forums/en/winforms/thread/0f49affb-90b9-4e26-8f60-b384236e5048
        /// </summary>
        /// <param name="tn"></param>
        /// <param name="nodeChecked"></param>
        private void CheckAllChildNodes(TreeNode tn, bool nodeChecked)
        {
            foreach (TreeNode node in tn.Nodes)
            {
                node.Checked = nodeChecked;
                if (node.Nodes.Count > 0)
                {
                    //if the current node has child nodes, call the CheckAllChildsNodes method recursively
                    this.CheckAllChildNodes(node, nodeChecked);
                }
            }
        }

        /// <summary>
        /// After a node is checked in the source treeview, replicate that change to all child nodes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Nodes.Count > 0)
            {
                // Calls the CheckAllChildNodes method, passing in the current
                // Checked value of the TreeNode whose checked state changed.
                this.CheckAllChildNodes(e.Node, e.Node.Checked);
            }
        }

        /// <summary>
        /// Populate the destination webservice endpoint combo box
        /// </summary>
        private void GenerateDstComboBox()
        {
            this.cboDstURL.DataSource = Properties.Settings.Default.ReportServicesURL;
            // set default value to be the second item in the list
            //this.cboDstURL.SelectedIndex = 1;
        }

        /// <summary>
        /// Populate the source webservice endpoint combo box
        /// </summary>
        private void GenerateSrcComboBox()
        {
            this.cboSrcURL.DataSource = Properties.Settings.Default.ReportServicesURL;
            //this.cboSrcURL.SelectedIndex = 1;
        }

        /// <summary>
        /// Generate the Source tree view
        /// </summary>
        private void GenerateSrcTreeView()
        {
            // clear out anything in the treeView first
            treeView1.Nodes.Clear();
            // make the cursor a wait cursor
            this.Cursor = Cursors.WaitCursor;
            // get the images that we use to assign to nodes in the tree view
            treeView1.ImageList = GenerateImageList();
            string srcpath = "/";
            //string srcURL = "http://wpdotappl06/ReportServer/ReportService2010.asmx";
            string srcURL = cboSrcURL.SelectedItem.ToString();

            CatalogItem srcLRT = new CatalogItem(srcURL);
            ReportService2010.CatalogItem[] srcitems = srcLRT.ListChildren(srcpath);
            // set up the root node
            TreeNode srcroot = new TreeNode();
            srcroot.Text = srcLRT.GetReportServerName();
            srcroot.ToolTipText = "Report Server Name";
            srcroot.ImageIndex = srcroot.SelectedImageIndex = 0;
            treeView1.Nodes.Add(srcroot);

            // build out the tree from root.  BeginUpdate disables rendering until EndUpdate()
            treeView1.BeginUpdate();
            foreach (ReportService2010.CatalogItem ci in srcitems)
            {
                AddTreeNodes(srcroot, ci, srcURL);
            }
            treeView1.EndUpdate();
            // set the cursor back to default
            this.Cursor = Cursors.Default;
            Console.WriteLine("Source tree built");
        }

        /// <summary>
        /// Generate the Destination tree view, displaying folders only
        /// </summary>
        private void GenerateDstTreeView()
        {
            // clear out anything in the treeView first
            treeView2.Nodes.Clear();
            // make the cursor a wait cursor
            this.Cursor = Cursors.WaitCursor;
            // Get the image list for our pretty icons
            treeView2.ImageList = GenerateImageList();
            // Our default path is always the root
            string dstpath = "/";
            //string dstURL = "http://xd0442dh:8080/ReportServer_SQL2008R2/ReportService2010.asmx";
            // get the path to the destination server
            string dstURL = cboDstURL.SelectedItem.ToString();

            CatalogItem dstLRT = new CatalogItem(dstURL);
            ReportService2010.CatalogItem[] dstitems = dstLRT.ListChildren(dstpath);
            // set up the root node
            TreeNode dstroot = new TreeNode();
            dstroot.Text = dstLRT.GetReportServerName();
            dstroot.ToolTipText = "Report Server Name";
            dstroot.ImageIndex = dstroot.SelectedImageIndex = 0;
            treeView2.Nodes.Add(dstroot);
            // build out the tree from root
            treeView2.BeginUpdate();
            foreach (ReportService2010.CatalogItem ci in dstitems)
            {
                // display only folders in this tree
                if (ci.TypeName == "Folder")
                    AddTreeNodes(dstroot, ci, dstURL);
            }
            treeView2.EndUpdate();
            // set the cursor back to default
            this.Cursor = Cursors.Default;
            Console.WriteLine("Destination tree built");
        }

        /// <summary>
        /// Generates an ImageList object that we use to put pretty icons in the tree view
        /// </summary>
        /// <returns>ImageList</returns>
        private ImageList GenerateImageList()
        {
            // new image list
            ImageList tvImageList = new ImageList();
            Stream _imageStream = null;
            Assembly _assembly = null;
            // get reference to current assembly
            _assembly = Assembly.GetExecutingAssembly();
            // get streams from our embedded resources and add them to the image list
            _imageStream = _assembly.GetManifestResourceStream("rsdeploygui.16fold.gif");
            tvImageList.Images.Add(new Bitmap(_imageStream));
            _imageStream = _assembly.GetManifestResourceStream("rsdeploygui.16datasource.gif");
            tvImageList.Images.Add(new Bitmap(_imageStream));
            _imageStream = _assembly.GetManifestResourceStream("rsdeploygui.16doc.gif");
            tvImageList.Images.Add(new Bitmap(_imageStream));
            _imageStream = _assembly.GetManifestResourceStream("rsdeploygui.16linked.gif");
            tvImageList.Images.Add(new Bitmap(_imageStream));
            _imageStream = _assembly.GetManifestResourceStream("rsdeploygui.16dataset.gif");
            tvImageList.Images.Add(new Bitmap(_imageStream));
            return tvImageList;
        }

        /// <summary>
        /// Add nodes to a given tree view
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="ci"></param>
        /// <param name="url"></param>
        private void AddTreeNodes(TreeNode parent, ReportService2010.CatalogItem ci, string url)
        {
            TreeNode newnode = new TreeNode();
            // the following are common among all nodes
            newnode.Text = ci.Name;
            newnode.Tag = ci;

            // these are used later in case we don't want to
            // generate all the catalog object types
            Boolean boolGenFolder = true;
            Boolean boolGenReport = true;
            Boolean boolGenDataSource = true;
            Boolean boolGenDataSet = true;
            Boolean boolGenLinkedReport = true;

            // Only generate Folders and LinkedReports if the action
            // combo box is Refresh Linked Report
            if (cboSelectAction.SelectedValue.ToString() == "Refresh Linked Reports")
            {
                boolGenReport = false;
                boolGenDataSource = false;
                boolGenDataSet = false;
            }

            if (ci.TypeName == "Folder" && boolGenFolder)
            {
                CatalogItem LRT = new CatalogItem(url);
                ReportService2010.CatalogItem[] items = LRT.ListChildren(ci.Path);
                newnode.ToolTipText = "Report Server Folder";
                newnode.ImageIndex = newnode.SelectedImageIndex = 0;
                parent.Nodes.Add(newnode);
                foreach (ReportService2010.CatalogItem cix in items)
                {
                    AddTreeNodes(newnode, cix, url);
                }
            }
            if (ci.TypeName == "Report" && boolGenReport)
            {
                newnode.ToolTipText = "Report Server Report";
                newnode.ImageIndex = newnode.SelectedImageIndex = 2;
                parent.Nodes.Add(newnode);
            }
            if (ci.TypeName == "DataSource" && boolGenDataSource)
            {
                newnode.ToolTipText = "DataSource";
                newnode.ImageIndex = newnode.SelectedImageIndex = 1;
                parent.Nodes.Add(newnode);
            }
            if (ci.TypeName == "LinkedReport" && boolGenLinkedReport)
            {
                newnode.ToolTipText = "Linked Report";
                newnode.ImageIndex = newnode.SelectedImageIndex = 3;
                parent.Nodes.Add(newnode);
            }
            if (ci.TypeName == "DataSet" && boolGenDataSet)
            {
                newnode.ToolTipText = "DataSet";
                newnode.ImageIndex = newnode.SelectedImageIndex = 4;
                parent.Nodes.Add(newnode);
            }
        }

        /// <summary>
        /// Copy folder(s) from source to destination
        /// </summary>
        private void CopyFolders()
        {
            // copy all selected folders from src tree to folder selected in dst tree
            String dstPath = "";
            String srcParentPath = "";
            Boolean blSrcRoot = true;

            // get catalog item for the destination parent path
            ReportService2010.CatalogItem dstParentPath = (ReportService2010.CatalogItem)treeView2.SelectedNode.Tag;
            // get new folder object pointing at the dest report server
            Folder fld = new Folder(cboDstURL.SelectedItem.ToString());

            foreach (ReportService2010.CatalogItem ci in getChecked(treeView1.Nodes))
            {
                // if this iteration is the FIRST iteration, get the srcParentPath
                if (blSrcRoot)
                {
                    // parent source path is what needs to be subtracted from the source
                    // path to get just the source folder and any subsequent folders
                    srcParentPath = ci.Path.Substring(0, ci.Path.IndexOf(ci.Name));
                    blSrcRoot = false;
                }
                // only add the ReportService2010.CatalogItem if it is a folder
                if (ci.TypeName == "Folder")
                {
                    // create the folder
                    dstPath = dstParentPath.Path + "/" + ci.Path.Substring(srcParentPath.Length);
                    if (fld.Create(dstPath))
                    {
                        Console.WriteLine("Folder created: {0}", dstPath);
                    }
                    else
                    {
                        Console.WriteLine("Folder not created: {0}", dstPath);
                    }
                }
            }

        }

        private void CopyDataSets()
        {
            Console.WriteLine("Copying datasets...");

            foreach (ReportService2010.CatalogItem ci in getChecked(treeView1.Nodes))
            {
                if (ci.TypeName == "DataSet")
                {
                    DataSet srcDataSet = new DataSet(cboSrcURL.SelectedItem.ToString());
                    DataSet dstDataSet = new DataSet(cboDstURL.SelectedItem.ToString());

                    // get reference for datasource for use in destination dataset
                    ItemReference[] irDSource = new ItemReference[1];
                    irDSource[0] = new ItemReference();

                    Boolean DataSourceExists = false;
                    // get the source parent path
                    String srcParentPath = ci.Path.Substring(0, ci.Path.IndexOf(ci.Name));
                    // get a catalog item from the destination so we can get parent path
                    ReportService2010.CatalogItem dstParentPath = (ReportService2010.CatalogItem)treeView2.SelectedNode.Tag;
                    // get the full dstPath
                    String dstPath = dstParentPath.Path + "/" + ci.Path.Substring(srcParentPath.Length);

                    #region future functionality (create datasources)
                    /*
                    // Get the datasource referenced by the source dataset
                    ItemReferenceData irdSrcDS = srcDataSet.getDataSourceItemReferenceData(ci.Path)[0];
                    // get the parent folder needed by the createDataSource method
                    String dstParentfolder = irdSrcDS.Reference.Substring(0, irdSrcDS.Reference.LastIndexOf("/"));
                    // Get the name needed by the createDataSource method
                    String dstDSName = irdSrcDS.Reference.Substring(irdSrcDS.Reference.LastIndexOf("/")+1);

                    // Get object in destination to check for datasource existence
                    DataSource dstDataSource = new DataSource(cboDstURL.SelectedItem.ToString());

                    // Check to see if the datasource exists in the destination
                    if (!(dstDataSource.Exists(irdSrcDS.Reference)))
                    {
                        // datasource does not exist, create it
                        DataSource srcDataSource = new DataSource(cboSrcURL.SelectedItem.ToString());
                        Console.WriteLine("{0} : {1} : {2}", ci.Name, dstParentfolder, dstDSName);
                        //dstDataSource.createDataSource(dstParentfolder, dstDSName, srcDataSource.getDataSourceDef(irdSrcDS.Reference));
                        DataSourceExists = true;
                    } else {
                        ItemReferenceData irdDstDS = dstDataSet.getDataSourceItemReferenceData(dstPath)[0];
                    }
                    // Datasource exists, go ahead and create the dataset
                    // get the source dataset definition
 */
                    #endregion future functionality (create datasources)

                    byte[] srcDefinition = srcDataSet.getDefinition(ci.Path);
                    
                    if (dstDataSet.Create(dstPath, srcDefinition))
                    {
                        Console.WriteLine("DataSet created: {0}", "");
                    }
                    else
                    {
                        Console.WriteLine("DataSet not created... :(");
                    }


                }
            }
            Console.WriteLine("Copying datasets complete.");

        }

        private void CopyLinkedReports()
        {
            Console.WriteLine("Copying linked reports...");
            foreach (ReportService2010.CatalogItem ci in getChecked(treeView1.Nodes))
            {
                if (ci.TypeName == "LinkedReport")
                {
                    // get objects for the source and destination items
                    rsdeploygui.CatalogItem srcItem = new rsdeploygui.CatalogItem(cboSrcURL.SelectedItem.ToString());
                    rsdeploygui.CatalogItem dstItem = new rsdeploygui.CatalogItem(cboDstURL.SelectedItem.ToString());

                    // get a collection of the parents
                    ReportService2010.CatalogItem[] srcParents = srcItem.ListParents(ci.Path);
                    // the first item in the collection is the immediate parent
                    // loop through all the parent items to find out which ones are checked
                    String srcFullParent = "";
                    foreach (ReportService2010.CatalogItem cip in srcParents)
                    {
                        foreach (ReportService2010.CatalogItem cic in getChecked(treeView1.Nodes))
                        {
                            //Check to see if the checked item is equal to the parent item
                            if (cip.Path == cic.Path)
                            {
                                srcFullParent = cip.Name + "/" + srcFullParent;
                            }
                        }
                    }

                    // Get the path of the selected destination folder, add on the srcFullParent
                    ReportService2010.CatalogItem dstParentItem = (ReportService2010.CatalogItem)treeView2.SelectedNode.Tag;
                    String dstParent = dstParentItem.Path + "/" + srcFullParent;
                    
                    // Create folder object to create in case it doesn't exist
                    rsdeploygui.Folder dstParentFolder = new rsdeploygui.Folder(cboDstURL.SelectedItem.ToString());

                    // Check to see if the source object for the linked report exists on the destination server
                    // need method here to get path to new RDL file

                    // if the parent folder exists, create the linkedreport
                    if (dstParentFolder.Exists(dstParent))
                    {

                        Console.WriteLine("dstItem.Create(\"LinkedReport\", {0}, {1}, true, def);", ci.Name, dstParent);
                    }
                    else
                    {
                        //parent folder doesn't exist, create it
                        dstParentFolder.Create(dstParent);
                        Console.WriteLine("CreateFolder({0})", dstParent);
                        Console.WriteLine("dstItem.Create(\"LinkedReport\", {0}, {1}, true, def);", ci.Name, dstParent);
                    }

                    //dstItem.Create("LinkedReport", ci.Name, ci.Path, true, srcItem.GetDef(ci.Path));
                }
            }
            Console.WriteLine("Done copying linked reports.");

        }

        /// <summary>
        /// When the index changes in the drop down box, populate the tree view
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cboDstURL_SelectedIndexChanged(object sender, EventArgs e)
        {
            GenerateDstTreeView();
        }

        private void cboSrcURL_SelectedIndexChanged(object sender, EventArgs e)
        {
            GenerateSrcTreeView();            
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                // Enable the next step, appropriate for whatever action was selected
                if (this.cboSelectAction.SelectedItem.ToString() == "Delete Items")
                {
                    // enable the last grouping containing the action button
                    this.grpLastStep.Enabled = true;
                }
                else if (this.cboSelectAction.SelectedItem.ToString() == "Copy Items")
                {
                    // enable group 3
                    this.grpStep3.Visible = true;
                    this.grpStep3.Enabled = true;
                    GenerateDstComboBox();
                }
                else if (this.cboSelectAction.SelectedItem.ToString() == "Refresh Linked Reports")
                {
                    // enable just the last step
                    this.grpLastStep.Enabled = true;
                }
                else if (this.cboSelectAction.SelectedItem.ToString() == "View Properties")
                {
                    this.grpLastStep.Enabled = true;
                }
            }

        }

    }
 }

